"""
订单处理模块 - 集成RabbitMQ消息队列
基于FastAPI实现订单创建和消息队列处理
"""
import pika
import json
import logging
from typing import Dict, Any
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel

logger = logging.getLogger(__name__)

try:
    from database import get_db, User
    from routers.dependencies import get_current_user
except ImportError as e:
    logger.error(f"导入依赖失败: {e}")
    # 创建临时的依赖函数用于测试
    from database.base import SessionLocal
    from models.models import User
    
    def get_db():
        db = SessionLocal()
        try:
            yield db
        finally:
            db.close()
    
    def get_current_user():
        # 临时的用户依赖，实际使用时需要正确的认证
        return User(id=1, username="test_user")

from config.settings import settings
from tools.order_stock import reserve_stock

router = APIRouter(prefix="/api/orders", tags=["订单管理"])


class OrderCreateRequest(BaseModel):
    """订单创建请求模型"""
    goods_ids: list[int]  # 商品ID列表
    quantities: list[int]  # 对应商品数量
    address_id: int = None  # 收货地址ID
    remark: str = ""  # 订单备注


class RabbitMQConfig:
    """RabbitMQ配置类"""
    def __init__(self):
        self.host = getattr(settings, 'RABBITMQ_HOST', '47.122.18.138')
        self.port = getattr(settings, 'RABBITMQ_PORT', 5672)
        self.username = getattr(settings, 'RABBITMQ_USERNAME', 'admin')
        self.password = getattr(settings, 'RABBITMQ_PASSWORD', 'admin')
        self.queue_name = 'order_queue'
        # 与已有队列参数保持一致，避免PRECONDITION_FAILED
        self.queue_arguments = {
            "x-max-priority": 10
        }
    
    def get_connection(self):
        """获取RabbitMQ连接"""
        try:
            credentials = pika.PlainCredentials(self.username, self.password)
            parameters = pika.ConnectionParameters(
                host=self.host,
                port=self.port,
                credentials=credentials
            )
            return pika.BlockingConnection(parameters)
        except Exception as e:
            logger.error(f"RabbitMQ连接失败: {e}")
            raise HTTPException(
                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
                detail="消息队列服务不可用"
            )


class OrderService:
    """订单服务类"""
    
    def __init__(self):
        self.rabbitmq_config = RabbitMQConfig()
    
    def generate_order_no(self) -> str:
        """生成订单号"""
        timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
        import random
        random_num = random.randint(1000, 9999)
        return f"XHS{timestamp}{random_num}"
    
    def send_to_queue(self, order_data: Dict[str, Any]) -> bool:
        """发送订单数据到RabbitMQ队列"""
        connection = None
        try:
            connection = self.rabbitmq_config.get_connection()
            channel = connection.channel()
            
            # 声明队列（如果不存在则创建）
            channel.queue_declare(
                queue=self.rabbitmq_config.queue_name,
                durable=True,
                arguments=self.rabbitmq_config.queue_arguments
            )
            
            # 发送消息
            channel.basic_publish(
                exchange='',
                routing_key=self.rabbitmq_config.queue_name,
                body=json.dumps(order_data, ensure_ascii=False, default=str),
                properties=pika.BasicProperties(
                    delivery_mode=2,  # 消息持久化
                )
            )
            
            logger.info(f"订单消息已发送到队列: {order_data['order_no']}")
            return True
            
        except Exception as e:
            logger.error(f"发送消息到队列失败: {e}")
            return False
        finally:
            if connection and not connection.is_closed:
                connection.close()


# 创建订单服务实例
order_service = OrderService()


@router.post("/create", summary="创建订单")
async def create_order(
    order_request: OrderCreateRequest,
    current_user: User = Depends(get_current_user)
):
    """
    创建订单并发送到RabbitMQ队列处理
    
    - **goods_ids**: 商品ID列表
    - **quantities**: 对应商品数量列表
    - **address_id**: 收货地址ID（可选）
    - **remark**: 订单备注
    """
    try:
        # 验证商品数量匹配
        if len(order_request.goods_ids) != len(order_request.quantities):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="商品ID和数量列表长度不匹配"
            )
        
        # 生成订单号
        order_no = order_service.generate_order_no()
        
        # Redis 预扣库存（不足直接返回）
        ok, msg = reserve_stock(order_no, order_request.goods_ids, order_request.quantities)
        if not ok:
            raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=msg)
        
        # 构建订单数据
        order_data = {
            "order_no": order_no,
            "user_id": current_user.id,
            "username": current_user.username,
            "goods_ids": order_request.goods_ids,
            "quantities": order_request.quantities,
            "address_id": order_request.address_id,
            "remark": order_request.remark,
            "status": "pending",  # 待处理
            "created_at": datetime.now(),
            "total_amount": 0,  # 将在消费者中计算
        }
        
        # 发送到RabbitMQ队列
        if order_service.send_to_queue(order_data):
            return {
                "code": 200,
                "message": "订单创建成功，正在处理中",
                "data": {
                    "order_no": order_no,
                    "status": "pending"
                }
            }
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="订单处理失败，请稍后重试"
            )
            
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建订单失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="订单创建失败"
        )


@router.get("/status/{order_no}", summary="查询订单状态")
async def get_order_status(
    order_no: str
    # 暂时移除依赖以便测试
    # current_user: User = Depends(get_current_user),
    # db: Session = Depends(get_db)
):
    """查询订单处理状态"""
    # 这里可以从数据库或缓存中查询订单状态
    # 暂时返回模拟数据
    return {
        "code": 200,
        "message": "查询成功",
        "data": {
            "order_no": order_no,
            "status": "processing",  # pending, processing, completed, failed
            "message": "订单正在处理中..."
        }
    }


@router.get("/test-connection", summary="测试RabbitMQ连接")
async def test_rabbitmq_connection():
    """测试RabbitMQ连接状态"""
    try:
        config = RabbitMQConfig()
        connection = config.get_connection()
        connection.close()
        return {
            "code": 200,
            "message": "RabbitMQ连接正常",
            "data": {
                "host": config.host,
                "port": config.port,
                "queue": config.queue_name
            }
        }
    except Exception as e:
        return {
            "code": 500,
            "message": f"RabbitMQ连接失败: {str(e)}",
            "data": None
        }
